#include <Windows.h>
#include <stdio.h>
#include "resource.h"
#include "fib_heap.h"
#include <string.h>
#include <time.h>

const char g_szClassName[] = "myWindowClass";
char *g_szRunClassName = "runClass";
char *g_szDrawClassName = "drawClass";
HINSTANCE hThisInstance;

#define IDBINOMIAL 4001
#define IDFIBONACCI 4002
#define IDLEFTIST 4003
#define IDRUNTIMES 4005
#define IDDRAWFH 4006
#define IDABOUT 4004

HWND hwndParent;

BOOL CALLBACK AboutProc(HWND,UINT,WPARAM,LPARAM);
BOOL CALLBACK FibonacciProc(HWND,UINT,WPARAM,LPARAM);
BOOL CALLBACK RunProc(HWND,UINT,WPARAM,LPARAM);

double fib_times[2][3],bin_times[3],left_times[3];
FH *H1=make_fib_heap(),*H2=make_fib_heap(),*H3=NULL;
FHE *AUX=NULL;
int fibStatus=0;

BOOL myRegClass(WNDPROC lpfnWndProc,char *szClassName,HINSTANCE hInst) {
	WNDCLASSEX wincl;

	wincl.hInstance=hInst;
	wincl.lpszClassName=szClassName;
	wincl.lpfnWndProc=lpfnWndProc;
	wincl.style=0;
	wincl.cbSize=sizeof(WNDCLASSEX);

	wincl.hIcon=LoadIcon(NULL,IDI_APPLICATION);
	wincl.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
	wincl.hCursor=LoadCursor(NULL,IDC_ARROW);
	wincl.lpszMenuName=NULL;
	wincl.cbClsExtra=0;
	wincl.cbWndExtra=0;
	wincl.hbrBackground=(HBRUSH)(COLOR_WINDOW);

	if(RegisterClassEx(&wincl))
		return TRUE;
	else
		return FALSE;
}

LRESULT CALLBACK childWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) {
	static int cxClient,cyClient;
	double time1,time2;
	char stime1[30],stime2[30],elem[30];
	char telem[50]="Number of elements: ";
	RECT emrect,dhrect,title,emin,dheap,elems;
	PAINTSTRUCT ps;
	HBRUSH hbrush;
	HDC hdc;
	switch(msg) {
	case WM_SIZE:
		cxClient=LOWORD(lParam);
		cyClient=HIWORD(lParam);
		return 0;
	case WM_PAINT:
		hdc=BeginPaint(hwnd,&ps);
		GetClientRect(hwnd,&emrect);
		GetClientRect(hwnd,&dhrect);
		GetClientRect(hwnd,&title);
		GetClientRect(hwnd,&emin);
		GetClientRect(hwnd,&dheap);
		GetClientRect(hwnd,&elems);
		SetTextColor(hdc,0x00000000);
		SetBkMode(hdc,COLOR_WINDOW);
		title.left=300;
		title.top=50;
		emin.left=322;
		emin.top=70;
		dheap.left=322;
		dheap.top=97;
		emrect.left=52;
		emrect.top=355;
		dhrect.left=112;
		dhrect.top=355;
		elems.top=370;
		elems.left=52;
		hbrush=CreateSolidBrush(RGB(0,0,255));
		SelectObject(hdc,hbrush);
		if(340-fib_times[0][0]*10000<50)
			Rectangle(hdc,50,50,100,350);
		else
			Rectangle(hdc,50,340-fib_times[0][0]*10000,100,350);
		Rectangle(hdc,300,70,320,90);
		hbrush=CreateSolidBrush(RGB(255,255,0));
		SelectObject(hdc,hbrush);
		sprintf(elem,"%.0f",fib_times[0][2]);
		time2=fib_times[0][0]*100;
		time1=fib_times[0][1]*100;
		strcat(telem,elem);
		sprintf(stime1,"%.3f",time1);
		sprintf(stime2,"%.3f",time2);
		if(340-fib_times[0][1]*10000<50)
			Rectangle(hdc,110,50,160,350);
		else
			Rectangle(hdc,110,340-fib_times[0][1]*10000,160,350);
		Rectangle(hdc,300,95,320,115);
		DrawText(hdc,stime2,-1,&emrect,DT_SINGLELINE|DT_NOCLIP);
		DrawText(hdc,stime1,-1,&dhrect,DT_SINGLELINE|DT_NOCLIP);
		DrawText(hdc,telem,-1,&elems,DT_SINGLELINE|DT_NOCLIP);
		DrawText(hdc,"FIBONACCI HEAPS",-1,&title,DT_SINGLELINE|DT_NOCLIP);
		DrawText(hdc,"extract-min",-1,&emin,DT_SINGLELINE|DT_NOCLIP);
		DrawText(hdc,"delete heap",-1,&dheap,DT_SINGLELINE|DT_NOCLIP);
		DeleteObject(SelectObject(hdc,hbrush));
	case WM_CREATE:
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
	case WM_DESTROY:
		
		break;
	default:
		return DefWindowProc(hwnd,msg,wParam,lParam);
	}
	return 0;
}

//linedirect 0=jos -1=stanga 1=dreapta
void draw_etl(int cx,int cy,int radius,int nr,int linedirect,HWND hwnd,HBRUSH hbrush,HDC hdc) {
	SelectObject(hdc,hbrush);
	Ellipse(hdc,cx-radius,cy-radius,cx+radius,cy+radius);
	char txt[10];
	itoa(nr,txt,10);
	RECT text;
	GetClientRect(hwnd,&text);
	text.left=cx-5;
	text.top=cy-4;
	DrawText(hdc,txt,-1,&text,DT_SINGLELINE|DT_NOCLIP);
	hbrush=CreateSolidBrush(0x00000000);
	SelectObject(hdc,hbrush);
	switch(linedirect) {
		case -1:
			MoveToEx(hdc,cx-radius,cy,NULL);
			LineTo(hdc,cx-radius-20,cy);
			break;
		case 1:
			MoveToEx(hdc,cx+radius,cy,NULL);
			LineTo(hdc,cx+radius+20,cy);
			break;
		case 0:
			MoveToEx(hdc,cx,cy+radius,NULL);
			LineTo(hdc,cx,cy+radius+20);
			break;
		default:
			break;
	}
}

void draw_heap_recur(FHE *fhe,HWND hwnd,int start_x,int start_y,HDC hdc,HBRUSH hbrush,int count,int elems) {
	if(fhe==NULL)
		return;
	FHE *left=fhe->left,*right=fhe->right;
	int left_pase=25+20;
	int right_pase=25+20;
	int height_pase=25+20;
	if(fhe->child) {
		draw_etl(start_x,start_y,25,fhe->key,0,hwnd,hbrush,hdc);
		count++;
		draw_heap_recur(fhe->child,hwnd,start_x,start_y+height_pase+25,hdc,hbrush,count,elems);
	}
	else {
		draw_etl(start_x,start_y,25,fhe->key,3,hwnd,hbrush,hdc);
		count++;
	}
	
	if(left != NULL && right != NULL) {
		if(fhe->parent) {
			if(fhe->parent->degree>0) {
				if(left==right && count < elems) {
					draw_etl(start_x-left_pase-25,start_y,25,left->key,1,hwnd,hbrush,hdc);
					count++;
					if(left->child)
						draw_heap_recur(left->child,hwnd,start_x-left_pase-25,start_y+height_pase+25,hdc,hbrush,count,elems);
				}
			}	
		}
		while(left!=right && count< elems) {
			draw_etl(start_x-left_pase-25,start_y,25,left->key,1,hwnd,hbrush,hdc); count++;
			draw_etl(start_x+right_pase+25,start_y,25,right->key,-1,hwnd,hbrush,hdc); count++;
			if(left->child)
				draw_heap_recur(left->child,hwnd,start_x-left_pase-25,start_y+height_pase+25,hdc,hbrush,count,elems);
			if(right->child)
				draw_heap_recur(right->child,hwnd,start_x+right_pase+25,start_y+height_pase+25,hdc,hbrush,count,elems);
			left_pase+=left_pase+25;		
			right_pase+=right_pase+25;
			left=left->left;
			right=right->right;
		}
	}
}


void draw_heap(HWND hwnd,FH *fh) {
	if(fh==NULL || fh->n==0 || fh->n>10)
		return;
	PAINTSTRUCT ps;
	HBRUSH hbrush;
	HDC hdc;
	RECT wnd_size;
	GetWindowRect(hwnd,&wnd_size);
	int width=wnd_size.right-wnd_size.left;
	int height=wnd_size.bottom-wnd_size.top;
	hdc=BeginPaint(hwnd,&ps);
	hbrush=CreateSolidBrush(RGB(255,0,0));
	SelectObject(hdc,hbrush);
	SetTextColor(hdc,RGB(255,255,255));
	SetBkMode(hdc,TRANSPARENT);
	int start_x=width/2;
	int start_y=wnd_size.top+100;
	draw_heap_recur(fh->min,hwnd,start_x,start_y,hdc,hbrush,0,fh->n);
	DeleteObject(SelectObject(hdc,hbrush));
}


LRESULT CALLBACK DrawProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) {
	switch(msg) {
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		break;
	case WM_PAINT:
		draw_heap(hwnd,H1);
		break;
	default:
		return DefWindowProc(hwnd,msg,wParam,lParam);
	}
}

static HWND drawWnd;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
	static HWND childWnd;
    switch(msg)
    {
		case WM_CREATE:
			CreateWindowEx(0, "BUTTON", "Binomial", WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 95+240-85, 200, 150, 23, hwnd, (HMENU)IDBINOMIAL, hThisInstance, 0);
			CreateWindowEx(0, "BUTTON", "Fibonacci", WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 95+240-85, 200+40, 150, 23, hwnd, (HMENU)IDFIBONACCI, hThisInstance, 0);
			CreateWindowEx(0, "BUTTON", "Leftist", WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 95+240-85, 200+80, 150, 23, hwnd, (HMENU)IDLEFTIST, hThisInstance, 0);
			CreateWindowEx(0, "BUTTON", "FHRT", WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 95+240-85 + 75 + 100, 200+40, 150, 23, hwnd, (HMENU)IDRUNTIMES, hThisInstance, 0);
			CreateWindowEx(0, "BUTTON", "DRAWFH", WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 95+240-85 - 75 - 100, 200+40, 150, 23, hwnd, (HMENU)IDDRAWFH, hThisInstance, 0);
			CreateWindowEx(0, "BUTTON", "About", WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 95+240-85, 200+120, 150, 23, hwnd, (HMENU)IDABOUT, hThisInstance, 0);
			return 0;
			break;
		case WM_COMMAND:
			switch(LOWORD(wParam)) {
			case IDABOUT:
				DialogBox(hThisInstance,MAKEINTRESOURCE(IDD_DIALOG1),hwndParent,AboutProc);
				break;
			case IDFIBONACCI:
				DialogBox(hThisInstance,MAKEINTRESOURCE(FIBONACCI_DIALOG),hwndParent,FibonacciProc);
				break;
			case IDRUNTIMES:
				childWnd=CreateWindowEx(0,
					g_szRunClassName,
					"FHRT",
					WS_OVERLAPPEDWINDOW|WS_VISIBLE,
					CW_USEDEFAULT,
					CW_USEDEFAULT,
					500,
					500,
					NULL,
					NULL,
					hThisInstance,
					NULL);
					break;
			case IDDRAWFH:
				drawWnd=CreateWindowEx(0,g_szDrawClassName,
					"DRAWFH",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
					CW_USEDEFAULT,CW_USEDEFAULT,
					1000,1000,NULL,NULL,hThisInstance,NULL);
				break;
			/*case IDBINOMIAL:
				DialogBox(hThisInstance,MAKEINTRESOURCE(IDD_DIALOG2),hwndParent,BinomialProc);
				break;*/
			}
			break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

	hThisInstance=hInstance;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

	if(myRegClass(childWndProc,g_szRunClassName,hThisInstance)==FALSE) {
		MessageBox(NULL,"Window Registration Failed2!","Error!",
			MB_ICONERROR|MB_OK);
		return 0;
	}

	if(myRegClass(DrawProc,g_szDrawClassName,hThisInstance)==FALSE) {
		MessageBox(NULL,"Window Registration Failed3!","Error!",
			MB_ICONERROR|MB_OK);
		return 0;
	}

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "HEAPS-EVALUATOR",
        WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
        CW_USEDEFAULT, CW_USEDEFAULT, 680, 480,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

	hwndParent=hwnd;

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

BOOL CALLBACK AboutProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) {
	switch(msg) {
	case WM_INITDIALOG:
		break;
	case WM_CLOSE:
		EndDialog(hwnd,0);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}


BOOL CALLBACK FibonacciProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) {
	switch(msg) {
	case WM_INITDIALOG:
		break;
	case WM_COMMAND:
		switch(LOWORD(wParam)) {
			case OPENH1:
				{
					OPENFILENAME ofn;
					char szFileName[MAX_PATH]="";

					ZeroMemory(&ofn,sizeof(ofn));

					ofn.lStructSize=sizeof(OPENFILENAME);
					ofn.hwndOwner=hwnd;
					ofn.lpstrFilter="Text Files (*.txt)\0*.txt\0All files(*.*)\0*.*\0";
					ofn.lpstrFile=szFileName;
					ofn.nMaxFile=MAX_PATH;
					ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
					ofn.lpstrDefExt="txt";

					if(GetOpenFileName(&ofn)) {
						FILE *fp=fopen(szFileName,"r");
						if(fp==NULL)
							MessageBox(hwnd,"ERROR OPENING FILE!","ERROR!",
								MB_ICONERROR|MB_OK);
						if(fp!=NULL) {
							if(H1->n==0) {
								int item=0,counter=0;
								while(!feof(fp)) {
									fscanf(fp,"%d",&item);
									AUX=make_fib_heap_elem(item);							
									fib_heap_insert(&H1,&AUX);									
									counter++;
								}
								if(H1->n==counter) {
									fib_times[0][2]=counter;
									MessageBox(hwnd,"FIRST HEAP WAS GENERATED FROM FILE!","SUCCESS!",
										MB_ICONINFORMATION|MB_OK);
								}
								else
									MessageBox(hwnd,"ERROR GENERATING HEAP!","ERROR!",
										MB_ICONERROR|MB_OK);
								fclose(fp);
							}
							else
								MessageBox(hwnd,"FIRST HEAP ALREADY GENERATED!","OOPS!",
									MB_ICONEXCLAMATION|MB_OK);
						}
					}
				}
				break;
			case GENERATEH1:
				if(H1->n==0) {
					BOOL sizeSuccess;
					int size=GetDlgItemInt(hwnd,EDIT1H1,&sizeSuccess,FALSE),i,randv=0;
					if(sizeSuccess) {
						fib_times[0][2]=size;
						char szsize[10];
						itoa(size,szsize,10);
						char message[50]="GENERATED WITH SIZE ";
						strcat(message,szsize);strcat(message,"!");
						for(i=0;i<size;i++) {
							randv=(rand() % size - 1)+1;
							AUX=make_fib_heap_elem(randv);
							fib_heap_insert(&H1,&AUX);
						}
						if(H1->n==size) {
							MessageBox(hwnd,message,"SUCCESS!",
								MB_ICONINFORMATION|MB_OK);
							draw_heap(drawWnd,H1);
						}
						else
							MessageBox(hwnd,"ERROR IN GENERATING HEAP OR GETTING THE SIZE!","ERROR!",
								MB_ICONERROR|MB_OK);
					}
				}
				else
					MessageBox(hwnd,"FIRST HEAP ALREADY GENERATED!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case INSERTH1:
				if(H1!=NULL) {
					int initSize=H1->n;char size[100];
					BOOL sizeSuccess;
					GetDlgItemText(hwnd,EDIT2H1,size,100);
					int szsize=atoi(size);
					char message[50]="INSERTED ELEMENT WITH KEY ";
					strcat(message,size);strcat(message,"!");
					AUX=make_fib_heap_elem(szsize);
					fib_heap_insert(&H1,&AUX);
					if(H1->n>initSize)
						MessageBox(hwnd,message,"SUCCESS!",
							MB_ICONINFORMATION|MB_OK);
					else
						MessageBox(hwnd,"ERROR INSERTING ITEM!","ERROR!",
							MB_ICONERROR|MB_OK);
				}
				else
					MessageBox(hwnd,"CRITICAL ERROR!","ERROR!",
						MB_ICONERROR|MB_OK);
				break;
			case FMINH1:
				if(H1->n>0) {
					AUX=find_min(H1);
					char szsize[10];
					char message[50]="ELEMENT WITH KEY: ";
					itoa(AUX->key,szsize,10);
					strcat(message,szsize);strcat(message," IS THE MINIMUM!");
					if(AUX)
						MessageBox(hwnd,message,"FOUND!",
							MB_ICONINFORMATION|MB_OK);
					else
						MessageBox(hwnd,"ERROR FINDING THE MINIMUM!","ERROR!",
							MB_ICONERROR|MB_OK);
				}
				else
					MessageBox(hwnd,"FIRST HEAP IS EMPTY!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case EMINH1:
				if(H1->n>0) {
					clock_t begin,end;
					double time_spent;
					begin=clock();
					AUX=fib_heap_extract_min(&H1);
					end=clock();
					char szsize[10];
					char message[50]="EXTRACTED THE ELEMENT WITH KEY: ";
					itoa(AUX->key,szsize,10);
					strcat(message,szsize);strcat(message," !");
					if(AUX) {
						time_spent=(double)(end-begin)/CLOCKS_PER_SEC;
						fib_times[0][0]=time_spent;
						MessageBox(hwnd,message,"EXTRACTED!",
							MB_ICONINFORMATION|MB_OK);
					}
					else
						MessageBox(hwnd,"ERROR EXTRACTING THE MINIMUM!","ERROR!",
							MB_ICONERROR|MB_OK);
				} else 
					MessageBox(hwnd,"FIRST HEAP IS EMPTY!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case DHEAPH1:
				clock_t begin,end;
				double time_spent;
				AUX=NULL;
				if(H1!=NULL && H1->n!=0) {
					begin=clock();
					AUX=fib_heap_extract_min(&H1);
					while(AUX!=NULL) {
						free(AUX);
						AUX=fib_heap_extract_min(&H1);
					}
					end=clock();
					free(H1);
					H1=make_fib_heap();
					if(H1->n==0) {
						time_spent=(double)(end-begin)/CLOCKS_PER_SEC;
						fib_times[0][1]=time_spent;
						MessageBox(hwnd,"FIRST HEAP DELETED!","SUCCESS!",
							MB_ICONINFORMATION|MB_OK);
					}
				} else
					MessageBox(hwnd,"FIRST HEAP IS EMPTY!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case OPENH2:
				{
					OPENFILENAME ofn;
					char szFileName[MAX_PATH]="";

					ZeroMemory(&ofn,sizeof(ofn));

					ofn.lStructSize=sizeof(OPENFILENAME);
					ofn.hwndOwner=hwnd;
					ofn.lpstrFilter="Text Files (*.txt)\0*.txt\0All files(*.*)\0*.*\0";
					ofn.lpstrFile=szFileName;
					ofn.nMaxFile=MAX_PATH;
					ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
					ofn.lpstrDefExt="txt";

					if(GetOpenFileName(&ofn)) {
						FILE *fp=fopen(szFileName,"r");
						if(fp==NULL)
							MessageBox(hwnd,"ERROR OPENING FILE!","ERROR!",
								MB_ICONERROR|MB_OK);
						if(fp!=NULL) {
							if(H2->n==0) {
								int item=0,counter=0;
								while(!feof(fp)) {
									fscanf(fp,"%d",&item);
									AUX=make_fib_heap_elem(item);
									fib_heap_insert(&H2,&AUX);
									counter++;
								}
								if(H2->n==counter) {
									fib_times[0][2]=counter;
									MessageBox(hwnd,"SECOND HEAP WAS GENERATED FROM FILE!","SUCCESS!",
										MB_ICONINFORMATION|MB_OK);
								}
								else
									MessageBox(hwnd,"ERROR GENERATING HEAP!","ERROR!",
										MB_ICONERROR|MB_OK);
								fclose(fp);
							}
							else
								MessageBox(hwnd,"SECOND HEAP ALREADY GENERATED!","OOPS!",
									MB_ICONEXCLAMATION|MB_OK);
						}
					}
				}
				break;
			case GENERATEH2:
				if(H2->n==0) {
					BOOL sizeSuccess;
					int size=GetDlgItemInt(hwnd,EDIT1H2,&sizeSuccess,FALSE),i,randv=0;
					if(sizeSuccess) {
						fib_times[0][2]=size;
						char szsize[10];
						itoa(size,szsize,10);
						char message[50]="GENERATED WITH SIZE ";
						strcat(message,szsize);strcat(message,"!");
						for(i=0;i<size;i++) {
							randv=(rand() % size - 1)+1;
							AUX=make_fib_heap_elem(randv);
							fib_heap_insert(&H2,&AUX);
						}
						if(H2->n==size)
							MessageBox(hwnd,message,"SUCCESS!",
								MB_ICONINFORMATION|MB_OK);
						else
							MessageBox(hwnd,"ERROR IN GENERATING HEAP OR GETTING THE SIZE!","ERROR!",
								MB_ICONERROR|MB_OK);
					}
				}
				else
					MessageBox(hwnd,"SECOND HEAP ALREADY GENERATED!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case INSERTH2:
				if(H2!=NULL) {
					int initSize=H2->n;char size[100];
					BOOL sizeSuccess;
					GetDlgItemText(hwnd,EDIT2H2,size,100);
					int szsize=atoi(size);
					char message[50]="INSERTED ELEMENT WITH KEY ";
					strcat(message,size);strcat(message,"!");
					AUX=make_fib_heap_elem(szsize);
					fib_heap_insert(&H2,&AUX);
					if(H2->n>initSize)
						MessageBox(hwnd,message,"SUCCESS!",
							MB_ICONINFORMATION|MB_OK);
					else
						MessageBox(hwnd,"ERROR INSERTING ITEM!","ERROR!",
							MB_ICONERROR|MB_OK);
				}
				else
					MessageBox(hwnd,"CRITICAL ERROR!","ERROR!",
						MB_ICONERROR|MB_OK);
				break;
			case FMINH2:
				if(H2->n>0) {
					AUX=find_min(H2);
					char szsize[10];
					char message[50]="ELEMENT WITH KEY: ";
					itoa(AUX->key,szsize,10);
					strcat(message,szsize);strcat(message," IS THE MINIMUM!");
					if(AUX)
						MessageBox(hwnd,message,"FOUND!",
							MB_ICONINFORMATION|MB_OK);
					else
						MessageBox(hwnd,"ERROR FINDING THE MINIMUM!","ERROR!",
							MB_ICONERROR|MB_OK);
				}
				else
					MessageBox(hwnd,"SECOND HEAP IS EMPTY!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case EMINH2:
				if(H2->n>0) {
					clock_t begin,end;
					double time_spent;
					begin=clock();
					AUX=fib_heap_extract_min(&H2);
					end=clock();
					char szsize[10];
					char message[50]="EXTRACTED THE ELEMENT WITH KEY: ";
					itoa(AUX->key,szsize,10);
					strcat(message,szsize);strcat(message," !");
					if(AUX) {
						time_spent=(double)(end-begin)/CLOCKS_PER_SEC;
						fib_times[0][0]=time_spent;
						MessageBox(hwnd,message,"EXTRACTED!",
							MB_ICONINFORMATION|MB_OK);
					}
					else
						MessageBox(hwnd,"ERROR EXTRACTING THE MINIMUM!","ERROR!",
							MB_ICONERROR|MB_OK);
				} else 
					MessageBox(hwnd,"SECOND HEAP IS EMPTY!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case DHEAPH2:
				AUX=NULL;
				if(H2!=NULL && H2->n!=0) {
					clock_t begin,end;
					double time_spent;
					AUX=fib_heap_extract_min(&H2);
					begin=clock();
					while(AUX!=NULL) {
						free(AUX);
						AUX=fib_heap_extract_min(&H2);
					}
					free(H2);
					H2=make_fib_heap();
					end=clock();
					if(H2->n==0) {
						time_spent=(double)(end-begin)/CLOCKS_PER_SEC;
						fib_times[0][1]=time_spent;
						MessageBox(hwnd,"SECOND HEAP DELETED!","SUCCESS!",
							MB_ICONINFORMATION|MB_OK);
					}
				} else
					MessageBox(hwnd,"SECOND HEAP IS EMPTY!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case UNIONH3:
				if(H1->n>0 && H2->n>0) {
					H3=fib_heap_union(H1,H2);
					if(H3!=NULL) {
						char message[50]="MADE UNION HEAP WITH SIZE: ";
						char szsize[10];
						itoa(H3->n,szsize,10);
						strcat(message,szsize);strcat(message," !");
						if(H3->n>0)
							MessageBox(hwnd,message,"SUCCESS!",
								MB_ICONINFORMATION|MB_OK);
						else
							MessageBox(hwnd,"CRITICAL ERROR!","ERROR!",
								MB_ICONERROR|MB_OK);
					}
					else 
						MessageBox(hwnd,"CRITICAL ERROR!","ERROR!",
								MB_ICONERROR|MB_OK);
				} else {
					if(!H1->n && !H2->n)
						MessageBox(hwnd,"FIRST GENERATE THE HEAPS ABOVE!","OOPS!",
							MB_ICONEXCLAMATION|MB_OK);
					if(!H1->n && H2->n)
						MessageBox(hwnd,"FIRST GENERATE THE FIRST HEAP!","OOPS!",
							MB_ICONEXCLAMATION|MB_OK);
					if(!H2->n && H1->n)
						MessageBox(hwnd,"FIRST GENERATE THE SECOND HEAP!","OOPS!",
							MB_ICONEXCLAMATION|MB_OK);
				}
				break;
			case INSERTH3:
				if(H3!=NULL) {
					int initSize=H3->n;char size[100];
					BOOL sizeSuccess;
					GetDlgItemText(hwnd,EDIT1H3,size,100);
					int szsize=atoi(size);
					char message[50]="INSERTED ELEMENT WITH KEY ";
					strcat(message,size);strcat(message,"!");
					AUX=make_fib_heap_elem(szsize);
					fib_heap_insert(&H3,&AUX);
					if(H3->n>initSize)
						MessageBox(hwnd,message,"SUCCESS!",
							MB_ICONINFORMATION|MB_OK);
					else
						MessageBox(hwnd,"ERROR INSERTING ITEM!","ERROR!",
							MB_ICONERROR|MB_OK);
				}
				else
					MessageBox(hwnd,"FIRST GENERATE THE HEAP WITH UNION","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
			case FMINH3:
				if(H3 && H3->n>0) {
					AUX=find_min(H3);
					char szsize[10];
					char message[50]="ELEMENT WITH KEY: ";
					itoa(AUX->key,szsize,10);
					strcat(message,szsize);strcat(message," IS THE MINIMUM!");
					if(AUX)
						MessageBox(hwnd,message,"FOUND!",
							MB_ICONINFORMATION|MB_OK);
					else
						MessageBox(hwnd,"ERROR FINDING THE MINIMUM!","ERROR!",
							MB_ICONERROR|MB_OK);
				}
				else
					MessageBox(hwnd,"UNION HEAP IS EMPTY!","OOPS!",
						MB_ICONEXCLAMATION|MB_OK);
				break;
		}
		break;
	case WM_CLOSE:
		/*AUX=NULL;
		if(!H3 && H1!=NULL && H1->n!=0) {
			clock_t begin,end;
			double time_spent;
			begin=clock();
			AUX=fib_heap_extract_min(&H1);
			while(AUX!=NULL) {
				free(AUX);
				AUX=fib_heap_extract_min(&H1);
			}
			free(H1);
			end=clock();
			time_spent=(double)(end-begin)/CLOCKS_PER_SEC;
			if(time_spent>fib_times[0][1])
				fib_times[0][1]=time_spent;
		}
		if(!H3 && H2!=NULL && H2->n!=0) {
			clock_t begin,end;
			double time_spent;
			begin=clock();
			AUX=fib_heap_extract_min(&H2);
			while(AUX!=NULL) {
				free(AUX);
				AUX=fib_heap_extract_min(&H2);
			}
			free(H2);
			free(H1);
			end=clock();
			time_spent=(double)(end-begin)/CLOCKS_PER_SEC;
			if(time_spent>fib_times[1][1])
				fib_times[1][1]=time_spent;
		}
		if(H3!=NULL && H3->n!=0) {
			AUX=fib_heap_extract_min(&H3);
			while(AUX!=NULL) {
				free(AUX);
				AUX=fib_heap_extract_min(&H3);
			}
			free(H3);
		}*/
		EndDialog(hwnd,0);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}
